package org.jsola.contract.service.impl;

import org.jsola.contract.common.ExampleKit;
import org.jsola.contract.constant.ContractConstants;
import org.jsola.contract.constant.ThirdChannelType;
import org.jsola.contract.dao.IContractCredentialDAO;
import org.jsola.contract.dto.ContractCredentialAddDTO;
import org.jsola.contract.dto.ContractCredentialSiteAddDTO;
import org.jsola.contract.dto.ContractCredentialSiteUpdateDTO;
import org.jsola.contract.dto.ContractCredentialUpdateDTO;
import org.jsola.contract.entity.ContractCredentialDO;
import org.jsola.contract.entity.ContractCredentialSiteDO;
import org.jsola.contract.query.ContractCredentialQuery;
import org.jsola.contract.service.IContractCredentialService;
import org.jsola.contract.service.IContractCredentialSiteService;
import org.jsola.contract.vo.ContractCredentialListVO;
import org.jsola.contract.vo.ContractCredentialVO;
import org.jsola.core.Page;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 电子合同账号凭证
 *
 * @author JanusMix
 */
@Service("contractContractCredentialServiceImpl")
public class ContractCredentialServiceImpl implements IContractCredentialService {

    @Autowired
    private IContractCredentialDAO contractCredentialDAO;
    @Autowired
    private IContractCredentialSiteService contractCredentialSiteService;

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public ContractCredentialVO save(ContractCredentialAddDTO contractCredentialAddDTO, TokenUser tokenUser) {
        // 转DO
        ContractCredentialDO contractCredentialDO = contractCredentialAddDTO.to(ContractCredentialDO.class);
        // 保存
        contractCredentialDO = save(contractCredentialDO, tokenUser.getSiteId(), tokenUser.getUserId());
        //保存站点模板绑定
        ContractCredentialSiteAddDTO contractCredentialSiteAddDTO = new ContractCredentialSiteAddDTO();
        contractCredentialSiteAddDTO.setContractCredentialId(contractCredentialDO.getId());
        contractCredentialSiteAddDTO.setCost(contractCredentialAddDTO.getCost());
        contractCredentialSiteService.save(contractCredentialSiteAddDTO, tokenUser);
        return contractCredentialDO.to(ContractCredentialVO.class);
    }

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public int update(ContractCredentialUpdateDTO contractCredentialUpdateDTO, TokenUser tokenUser) {
        //转DO
        ContractCredentialDO contractCredentialDO = contractCredentialUpdateDTO.to(ContractCredentialDO.class);
        //更新站点模板绑定
        ContractCredentialSiteUpdateDTO contractCredentialSiteUpdateDTO = new ContractCredentialSiteUpdateDTO();
        contractCredentialSiteUpdateDTO.setContractCredentialId(contractCredentialDO.getId());
        contractCredentialSiteUpdateDTO.setCost(contractCredentialUpdateDTO.getCost());
        contractCredentialSiteService.update(contractCredentialSiteUpdateDTO, tokenUser);
        //根据主键更新，只更新非null值
        return updateByIdSelective(contractCredentialDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    @Override
    @Transactional(value = ContractConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... contractCredentialIds) {
        int count = logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) contractCredentialIds);
        //删除租户绑定
        for (String id : contractCredentialIds) {
            contractCredentialSiteService.deleteByCredentialId(id, tokenUser);
        }
        return count;
    }


    @Override
    public ContractCredentialVO selectById(String contractCredentialId, String siteId) {
        ContractCredentialDO contractCredentialDO = selectDOById(contractCredentialId, siteId);
        if (contractCredentialDO == null) {
            return null;
        }
        return contractCredentialDO.to(ContractCredentialVO.class);
    }

    @Override
    public List<ContractCredentialListVO> select(ContractCredentialQuery contractCredentialQuery, String siteId) {
        List<ContractCredentialDO> contractCredentialDOList = selectDO(contractCredentialQuery, siteId);
        if(CollectionUtils.isEmpty(contractCredentialDOList)) {
            return contractCredentialDOList == null ? null : new ArrayList<>();
        }
        return contractCredentialDOList.stream()
                .map(contractCredentialDO -> contractCredentialDO.to(ContractCredentialListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(ContractCredentialQuery contractCredentialQuery, String siteId) {
        Example example = buildExample(contractCredentialQuery,siteId);
        return contractCredentialDAO.selectCountByExample(example);
    }

    @Override
    public Page<ContractCredentialListVO> selectPage(ContractCredentialQuery contractCredentialQuery, String siteId) {
        Example example = buildExample(contractCredentialQuery,siteId);
        Page<ContractCredentialDO> page = contractCredentialDAO.selectPageByExample(example,
                contractCredentialQuery.getPageNo(),
                contractCredentialQuery.getPageSize());

        return page.to(ContractCredentialListVO.class);
    }

    @Override
    public ContractCredentialDO selectDOById(String contractCredentialId, String siteId) {
        return listById(contractCredentialId, siteId);
    }

    @Override
    public List<ContractCredentialDO> selectDO(ContractCredentialQuery contractCredentialQuery, String siteId) {
        Example example = buildExample(contractCredentialQuery,siteId);
        return contractCredentialDAO.selectByExample(example);
    }

    @Override
    public List<ContractCredentialDO> selectAll() {
        Example example = new Example(ContractCredentialDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("thirdChannel", ThirdChannelType.ESIGN.getValue());
        return contractCredentialDAO.selectByExample(example);
    }

    @Override
    public ContractCredentialVO selectBySiteId(TokenUser tokenUser) {
        Example example = new Example(ContractCredentialDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        List<ContractCredentialDO> credentialList = contractCredentialDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(credentialList)) {
            return new ContractCredentialVO();
        }
        ContractCredentialVO contractCredentialVO = credentialList.get(0).to(ContractCredentialVO.class);
        ContractCredentialSiteDO contractCredentialSiteDO = contractCredentialSiteService.selectByCredentialId(contractCredentialVO.getId(), tokenUser);
        if (contractCredentialSiteDO != null) {
            contractCredentialVO.setCost(contractCredentialSiteDO.getCost());
        }
        return contractCredentialVO;
    }


    /**
     * 根据查询参数，构建example

     * @param contractCredentialQuery 查询参数
     * @param siteId 所属站点id
     * @return example
     */
    private Example buildExample(ContractCredentialQuery contractCredentialQuery, String siteId) {
        Example example = new Example(ContractCredentialDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        // 排序
        ExampleKit.setExampleOrder(example,contractCredentialQuery.getOrders());
        return example;
    }
}




